package com.weiiew.backend.executor;

import com.weiiew.backend.entity.enums.ExecutorState;
import com.weiiew.backend.exception.ExecutorParamsException;
import com.weiiew.backend.operationUtils.OperationExecutor;
import com.weiiew.backend.utils.ErrorWebSocketUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.awt.*;

/**
 * @Description 基础执行器，封装了状态转化保证了多线程安全
 * @Author 魏锴
 * @Date 2025/4/28
 */
@Slf4j
@Component
public abstract class baseExecutor<T> {
    protected final Object lock = new Object(); // 用于在执行操作转化时保证不会相互干扰
    @Autowired
    protected SimpMessagingTemplate messagingTemplate;
    protected OperationExecutor executor;

    /**
     * 创建操作执行器
     */
    @PostConstruct
    private void init() {
        try {
            executor = new OperationExecutor();
        } catch (AWTException e) {
            e.printStackTrace();
            ErrorWebSocketUtil.sendError("init", "执行器创建失败，缺少必要权限");
        }
    }

    /**
     * 负责加载OperationExecutor
     *
     * @param config 配置类
     */
    protected abstract void initResource(T config) throws ExecutorParamsException;

    protected abstract void clearResource();

    public void start(T config) {
        try {
            synchronized (lock) {
                initResource(config);
                executor.start();
            }
        } catch (ExecutorParamsException e) {
            ErrorWebSocketUtil.sendError("mouse", e.getMessage());
        }
    }

    public void stop() {
        synchronized (lock) {
            if (executor != null) executor.stop();
            clearResource();
        }
    }

    public void pause() {
        synchronized (lock) {
            if (executor != null) executor.pause();
        }
    }

    public void resume() {
        synchronized (lock) {
            if (executor != null) executor.resume();
        }
    }

    public void toggle(T config) {
        try {
            synchronized (lock) {
                if (executor.getState() == ExecutorState.STOP
                        || executor.getState() == ExecutorState.READY) initResource(config);
                executor.toggle();
                if (executor.getState() == ExecutorState.STOP) clearResource();
            }
        } catch (ExecutorParamsException e) {
            ErrorWebSocketUtil.sendError("mouse", e.getMessage());
        }
    }

    public void startStopToggle(T config) {
        try {
            synchronized (lock) {
                if (executor.getState() == ExecutorState.STOP
                        || executor.getState() == ExecutorState.READY) initResource(config);
                executor.startStopToggle();
                if (executor.getState() == ExecutorState.STOP) clearResource();
            }
        } catch (ExecutorParamsException e) {
            ErrorWebSocketUtil.sendError("mouse", e.getMessage());
        }
    }

    public void reset() {
        synchronized (lock) {
            if (executor != null) executor.reset();
        }
    }

    public ExecutorState getState() {
        synchronized (lock) {
            if (executor == null) return null;
            return executor.getState();
        }
    }
}
